函式
<new>

operator delete

普通 (1)
void operator delete (void* ptr) throw();
nothrow (2)
void operator delete (void* ptr, const std::nothrow_t& nothrow_constant) throw();
placement (3)
void operator delete (void* ptr, void* voidptr2) throw();
普通 (1)
void operator delete (void* ptr) noexcept;
nothrow (2)
void operator delete (void* ptr, const std::nothrow_t& nothrow_constant) noexcept;
placement (3)
void operator delete (void* ptr, void* voidptr2) noexcept;
普通 (1)
void operator delete (void* ptr) noexcept;
nothrow (2)
void operator delete (void* ptr, const std::nothrow_t& nothrow_constant) noexcept;
placement (3)
void operator delete (void* ptr, void* voidptr2) noexcept;
帶大小 (4)
void operator delete (void* ptr, std::size_t size) noexcept;
nothrow 帶大小 (5)
void operator delete (void* ptr, std::size_t size,                      const std::nothrow_t& nothrow_constant) noexcept;
釋放儲存空間
預設的*解構函式*(單物件形式)。

(1) 普通 delete
釋放 ptr 指向的記憶體塊(如果非空),釋放之前透過呼叫 operator new 分配給它的儲存空間,並使該指標位置失效。
(2) nothrow delete
同上(1)
(3) placement delete
什麼都不做。
(1) 普通 delete
釋放 ptr 指向的記憶體塊(如果非空),釋放之前透過呼叫 operator new 分配給它的儲存空間,並使該指標位置失效。
(2) nothrow delete
同上(1)
預設定義呼叫第一個版本(1): ::operator delete(ptr)
(3) placement delete
什麼都不做。
(1) 普通 delete
釋放 ptr 指向的記憶體塊(如果非空),釋放之前透過呼叫 operator new 分配給它的儲存空間,並使該指標位置失效。
(2) nothrow delete
同上(1)
預設定義呼叫第一個版本(1): ::operator delete(ptr)
(3) placement delete
什麼都不做。
(4) (5) 帶大小
分別同(1)(2)
預設定義簡單地呼叫相應版本:(1)(2)
它們為自定義實現提供了最佳化點:它們被呼叫時會傳入與相應*分配函式*呼叫時相同的*大小*引數。

請注意,如果其中一個帶*size*的簽名被替換,那麼它對應的無*size*的版本也應該被替換(反之亦然)。即:如果(1)(4)被替換,兩者都應該被替換。同樣,如果(2)(5)被替換,兩者都應該被替換。

預設的*分配和解構函式*是標準庫的特殊元件;它們具有以下獨特屬性
  • 全域性: 所有 operator delete 的過載都在全域性名稱空間中宣告,而不是在 std 名稱空間內。
  • 隱式: 析構版本(即除(3)外的所有版本)在 C++ 程式的每個翻譯單元中*隱式宣告*,無論是否包含標頭檔案<new>
  • 可替換:析構版本(即除(3)外的所有版本)也*可替換*:程式可以提供自己的定義來替換預設提供的定義,或者可以為特定型別過載它。自定義定義應釋放 ptr 引用的儲存。

operator delete 是一個常規函式,可以像任何其他函式一樣顯式呼叫。但在 C++ 中,delete 是一個具有非常特定行為的運算子:帶有 delete 運算子的表示式首先呼叫適當的解構函式(對於類型別),然後呼叫*解構函式*。

類物件的*解構函式*是名為 operator delete 的成員函式(如果存在)。在所有其他情況下,它是全域性函式 operator delete(即此函式——或更具體的過載)。如果 delete 表示式前面帶有*作用域運算子*(即 ::operator delete),則只考慮全域性*解構函式*。

使用全域性*解構函式*的 delete 表示式始終呼叫單引數簽名(例如(1))。
使用全域性*解構函式*的 delete 表示式始終使用接受指標(例如(1))或指標和大小(例如(4))的簽名。總是優先使用帶*size*的版本(4),除非過載提供了與指標型別更匹配的匹配。

其他簽名((2)(3))*從不*被*delete表示式*呼叫(delete 運算子始終呼叫此函式的普通版本,並且每個引數只調用一次)。這些其他簽名僅在物件構造失敗時由*new表示式*自動呼叫(例如,如果物件的建構函式在由帶 nothrow 的*new表示式*構造時丟擲異常,則會呼叫接受 nothrow 引數的匹配 operator delete 函式)。

非成員*解構函式*不得在全域性名稱空間以外的名稱空間作用域中宣告。

引數

ptr
指向要釋放的記憶體塊的指標,型別轉換為 void*
如果這是一個*空指標*,則函式不執行任何操作。
如果非空,此指標值應由先前呼叫 operator new 返回,並且尚未透過先前呼叫此函式被釋放。
如果非空,此指標值應由先前呼叫 operator new 返回,並且尚未透過先前呼叫此函式被釋放。
如果實現具有*嚴格指標安全性*,則此指標還應為*安全派生指標*。
nothrow_constant
常量 nothrow。此引數在預設定義中被忽略。
nothrow_t 是常量 nothrow 的型別。
voidptr2
void指標。該值在預設定義中被忽略。
size
在分配記憶體塊時傳遞給*分配函式*的第一個引數。
std::size_t 是無符號整數型別。

返回值



示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// operator delete example
#include <iostream>     // std::cout

struct MyClass {
  MyClass() {std::cout <<"MyClass constructed\n";}
  ~MyClass() {std::cout <<"MyClass destroyed\n";}
};

int main () {
  MyClass * pt = new (std::nothrow) MyClass;
  delete pt;    // implicitly calls ::operator delete(pt)

  return 0;
}

輸出

MyClass constructed
MyClass destroyed


資料競爭

修改 ptr 引用的儲存。
呼叫*分配和解構函式*會重用相同的儲存單元,並按照一個總順序進行,其中每次析構都發生在下一次分配之前。
這同樣適用於此函式的自定義替換的可觀察行為。

異常安全

無異常保證:此函式從不丟擲異常。

請注意,無效的 ptr 值會導致未定義行為。
請注意,無效的 ptr 值或與*分配函式*傳遞的*size*值不匹配的值會導致未定義行為。

另見